package ensemble.samples.custom.sqlformat.javafx.fxml;

import static ensemble.samples.custom.sqlformat.javafx.util.AppContext.contentOutput;
import static ensemble.samples.custom.sqlformat.javafx.util.AppContext.getContentFromInput;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import ensemble.samples.custom.sqlformat.javafx.util.AppContext;
import ensemble.samples.custom.sqlformat.javafx.util.GroovyUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.stage.FileChooser;

/**
 * @author duanxq
 * @date 2021/6/28
 */
public class TextSimpleController {

    private int historyLength = 10;
    private int historyIndex = historyLength - 1;
    private LinkedList<String> history = new LinkedList<>();

    @FXML
    private TextArea inputTextArea;


    private ImmutableMap<String, String> openFileMap = ImmutableMap.of("csv2Excel", "*.csv");
    private List<String> asyncButton = Lists.newArrayList("csv2Excel");

    @FXML
    private void common(ActionEvent event) {
        AppContext.setInputTextArea(inputTextArea);
        Button button = (Button) event.getTarget();
        String buttonId = button.getId();

        String getHistoryByIndex = getHistoryByIndex(buttonId);
        if (getHistoryByIndex != null) {
            contentOutput(getHistoryByIndex);
            return;
        }
        Object input;
        if (isOpenFile(buttonId)) {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("select your file");
            fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("All Files",
                openFileMap.get(buttonId)));
            List<File> files = fileChooser.showOpenMultipleDialog(AppContext.getStage());
            if (files == null) {
                // 没有选择文件
                return;
            }
            input = files.stream().map(File::getAbsolutePath).collect(Collectors.toList());
        } else {
            input = getContentFromInput();
        }
        Runnable task = () -> {
            String s = (String) GroovyUtils.invokeMethod(buttonId, input);
            if (s != null) {
                contentOutput(s);
                if (input instanceof String) {
                    recordToHistory((String) input, s);
                }
            }
        };
        if (isAsyncButton(buttonId)) {
            CompletableFuture.runAsync(task, AppContext.getExecutorService());
        } else {
            task.run();
        }


    }

    private boolean isOpenFile(String buttonId) {
        return openFileMap.keySet().contains(buttonId);
    }

    private boolean isAsyncButton(String buttonId) {
        return asyncButton.contains(buttonId);
    }


    private void recordToHistory(String input, String output) {
        checkAdd(input, output);
        historyIndex = historyLength - 1;
    }

    private void checkAdd(String... ss) {
        for (final String s : ss) {
            if (history.contains(s)) {
                history.remove(s);
                history.add(s);
                continue;
            }
            if (history.size() >= historyLength) {
                history.remove();
            }
            history.add(s);
        }
    }


    private String getHistoryByIndex(String buttonId) {
        ArrayList<String> historyButton = Lists.newArrayList("l", "ll", "r", "rr");
        if (!historyButton.contains(buttonId)) {
            return null;
        }
        if (history.size() == 0) {
            return null;
        }
        historyIndex = Math.max(0, historyIndex);
        historyIndex = Math.min(historyIndex, history.size() - 1);
        if ("l".equals(buttonId)) {
            historyIndex--;
        }
        if ("ll".equals(buttonId)) {
            historyIndex = 0;
        }
        if ("r".equals(buttonId)) {
            historyIndex++;
        }
        if ("rr".equals(buttonId)) {
            historyIndex = history.size() - 1;
        }
        historyIndex = Math.max(0, historyIndex);
        historyIndex = Math.min(historyIndex, history.size() - 1);
        return history.get(historyIndex);
    }

}
